package co.gov.medellin.ssti.sub.service;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;

import javax.naming.NamingException;

import co.gov.medellin.ssti.sub.common.ConexionFactory;
import co.gov.medellin.ssti.sub.common.excepcion.SUBException;
import co.gov.medellin.ssti.sub.model.dao.DAOFactory;
import co.gov.medellin.ssti.sub.model.dao.IBeneficiarioDAO;
import co.gov.medellin.ssti.sub.model.dao.exception.DAOException;
import co.gov.medellin.ssti.sub.model.vo.BeneficiarioVO;
import co.gov.medellin.ssti.sub.model.vo.BeneficioVO;

public class BeneficiarioService {
	/**
	 * 
	 * @param criteria
	 * @return
	 * @throws SQLException
	 */
	public Collection<BeneficiarioVO> findBeneficiarioMEL(
			BeneficiarioVO criteria) throws DAOException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.findBeneficiarioMEL(criteria);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}

	/**
	 * 
	 * @param criteria
	 * @return
	 * @throws SQLException
	 */
	public Collection<BeneficiarioVO> findBeneficiarioSisben(
			BeneficiarioVO criteria) throws DAOException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.findBeneficiarioSisben(criteria);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}

	/**
	 * Obtiene el grupo familiar de un integrante del sistema SISBEN3, a partir
	 * de su tipo y numero de documento, estos valores deben ser numericos que
	 * es como estan registrados en el SISBEN, pero se envian como un String.
	 * 
	 * @param tipoDoc
	 *            Tipo de documento del integrante del grupo familiar.
	 * @param numDoc
	 *            Numero de documento del integrante del grupo familiar.
	 * @return Collection de BeneficiarioVO con las personas que pertenecen al
	 *         grupo familiar.
	 * @throws SQLException
	 *             Si falla la ejecucion del query por tipos de parametros o
	 *             problemas en la base de datos.
	 * @throws SUBException
	 *             Por la falla en alguna conexion con el API.
	 */
	public Collection<BeneficiarioVO> findGrupoFamiliarSisben(String tipoDoc,
			String numDoc) throws DAOException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.findGrupoFamiliarSisben(tipoDoc, numDoc);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}

	/**
	 * 
	 * @param criteria
	 * @param strOrigen
	 * @return
	 * @throws SQLException
	 */
	public Collection<BeneficiarioVO> findBeneficiarioByCriteria(
			BeneficiarioVO criteria, String strOrigen) throws DAOException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.findBeneficiarioByCriteria(criteria,
					strOrigen);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}

	/**
	 * Metodo.
	 * 
	 * @param criteria
	 * @param strOrigen
	 * @param codePrograma
	 * @param codeSubprograma
	 * @return
	 * @throws SQLException
	 */
	public Collection<BeneficiarioVO> findBeneficiarioByCriteria(
			BeneficiarioVO criteria, String strOrigen, Long codePrograma,
			Long codeSubprograma) throws DAOException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.findBeneficiarioByCriteria(criteria,
					strOrigen, codePrograma, codeSubprograma);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}

	/**
	 * 
	 * @param criteria
	 * @return
	 * @throws SQLException
	 */
	public int update(BeneficiarioVO criteria) throws DAOException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.update(criteria);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}

	/**
	 * 
	 * @param criteria
	 * @return
	 * @throws SQLException
	 */
	public Collection<BeneficiarioVO> findCabezasGrupoFamiliar(
			BeneficiarioVO criteria) throws DAOException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.findCabezasGrupoFamiliar(criteria);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}

	/**
	 * 
	 * @param criteria
	 * @return
	 * @throws SQLException
	 */
	public Collection<BeneficiarioVO> findGrupoFamiliar(BeneficiarioVO criteria)
			throws DAOException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.findGrupoFamiliar(criteria);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}

	/**
	 * 
	 * @param codeBeneficiario
	 * @return
	 * @throws SQLException
	 */
	public String findEdad(Long codeBeneficiario) throws DAOException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.findEdad(codeBeneficiario);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}

	/**
	 * 
	 * @param criteria
	 * @return
	 * @throws SQLException
	 */
	public String[] insert(BeneficiarioVO criteria) throws DAOException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.insert(criteria);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}

	/**
	 * Metodo que consulta en VCS_BENEFICIOS_OTORGADOS para obtener los
	 * beneficios otorgados al beneficiario.
	 * 
	 * @param codeBeneficiario
	 *            Codigo del beneficiario.
	 * @return Collecion de BeneficioVO.
	 * @throws SQLException
	 */
	public Collection<BeneficioVO> findBeneficiosByCodBen(Long codeBeneficiario)
			throws DAOException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.findBeneficiosByCodBen(codeBeneficiario);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}

	/**
	 * Metodo que consulta en VCS_BENEFICIOS_OTORGADOS los ultimos beneficios
	 * otorgados al beneficiario.
	 * 
	 * @param codeBeneficiario
	 *            Codigo del beneficiario.
	 * @return Collecion de BeneficioVO.
	 * @throws SQLException
	 */
	public Collection<BeneficioVO> findUltimosBeneficios(Long codeBeneficiario)
			throws DAOException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.findUltimosBeneficios(codeBeneficiario);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}

	/**
	 * Metodo que realiza un borrado logico del beneficiario. Se realiza un
	 * update en TCS_BEN_BENEFICIARIO: CAMPO_A1 = 'S', usuario_modifica = "WEB="
	 * + terminal, fecha_modifica = fecha.
	 * 
	 * @param codeBeneficiario
	 *            Codigo del beneficiario.
	 * @param user
	 *            Usuario que llama el metodo.
	 * @param terminal
	 *            Terminal desde donde se llama el metodo.
	 * @param fecha
	 *            Fecha en la cual se llama el metodo.
	 * @return true si se realiza el update.
	 */
	public boolean delete(Long codeBeneficiario, String user, String terminal,
			String fecha) throws DAOException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.delete(codeBeneficiario, user, terminal,
					fecha);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}

	/**
	 * 
	 * @param codeBeneficiario
	 * @param codeBeneficio
	 * @param user
	 * @param terminal
	 * @param fecha
	 * @return
	 * @throws SQLException
	 */
	public boolean deleteBeneficio(Long codeBeneficiario, Long codeBeneficio,
			String user, String terminal, String fecha) throws SQLException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.deleteBeneficio(codeBeneficiario,
					codeBeneficio, user, terminal, fecha);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}

	/**
	 * Metodo para consultar si un beneficiario esta en la tabla
	 * TCS_BEN_BENEF_GRUPO_FAMILIAR.
	 * 
	 * @param codigoBeneficiario
	 *            Codigo del beneficiario.
	 * @param codigoGrupoFamiliar
	 *            Codigo del grupo familiar.
	 * @return true si esta asignado al grupo familiar.
	 * @throws SQLException
	 */
	public boolean isBeneficiarioAsignadoAGrupoFamiliar(
			Long codigoBeneficiario, Long codigoGrupoFamiliar)
			throws DAOException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.isBeneficiarioAsignadoAGrupoFamiliar(
					codigoBeneficiario, codigoGrupoFamiliar);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}

	/**
	 * Metodo que consulta en VCS_BENEFICIOS_OTORGADOS para determinar si el
	 * beneficiario tiene beneficios del subprograma con codigo codeSubprograma.
	 * 
	 * @param codeBeneficiario
	 *            Codigo del beneficiario.
	 * @param codeSubprograma
	 *            Codigo del subprograma.
	 * @return true si el beneficiario tiene beneficios de ese subprograma.
	 *         false en caso contrario.
	 * @throws SQLException
	 */
	public boolean isBeneficiarioSubprograma(Long codeBeneficiario,
			Long codeSubprograma) throws DAOException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.isBeneficiarioSubprograma(codeBeneficiario,
					codeSubprograma);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}

	/**
	 * Metodo que retorna BEN_CODIGO del registro en TCS_BEN_BENEFICIO_OTORGADO
	 * con codigo = codeBOT.
	 * 
	 * @param codeBOT
	 *            Codigo del beneficio otorgado.
	 * @return Codigo del beneficiario.
	 * @throws SQLException
	 */
	public Long findCodeBeneficiarioByCodeBOT(Long codeBOT) throws DAOException {
		IBeneficiarioDAO beneficiarioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficiarioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficiarioDAO(con);
			return beneficiarioDAO.findCodeBeneficiarioByCodeBOT(codeBOT);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficiarioDAO != null) {
				if (!beneficiarioDAO.isConnClosed()) {
					beneficiarioDAO.close();
				}
			}
		}
	}
}
